package handler

import (
	"context"
	"github.com/astaxie/beego/logs"
	"github.com/astaxie/beego/orm"
	"github.com/garyburd/redigo/redis"
	"ihome/models"
	"ihome/utils"
	"time"

	"github.com/micro/go-micro/util/log"

	register "ihome/proto/register"
)

type Register struct{}

// Call is a single request handler called via client.Call or the generated client code
func (e *Register) SrvRegister(ctx context.Context, req *register.Request, rsp *register.Response) error {
	logs.Info("获取短信验证码 SrvRegister /api/v1.0/register")

	rsp.Code = utils.RecodeOk
	rsp.Msg = utils.RecodeText(rsp.Code)

	/*验证短信验证码*/
	bm, err := utils.NewCache()
	if err != nil {
		logs.Info("redis连接失败", err)
		rsp.Code = utils.RecodeDberr
		rsp.Msg = utils.RecodeText(rsp.Code)
		return nil
	}

	smsCode := bm.Get(req.Mobile)
	if smsCode == nil {
		logs.Info("redis获取验证码缓存失败", err)
		rsp.Code = utils.RecodeDberr
		rsp.Msg = utils.RecodeText(rsp.Code)
		return nil
	}
	smsCodeStr, _ := redis.String(smsCode, nil)
	if smsCodeStr != req.SmsCode {
		logs.Info("验证码错误", err)
		rsp.Code = utils.RecodeSmsError
		rsp.Msg = utils.RecodeText(rsp.Code)
		return nil
	}

	/*将数据存入数据库*/
	o := orm.NewOrm()
	user := models.User{
		Mobile:        req.Mobile,
		Password_hash: utils.MD5String(req.Password),
		Name:          req.Mobile,
	}
	id, err := o.Insert(&user)
	if err != nil {
		logs.Info("注册数据失败")
		rsp.Code = utils.RecodeDberr
		rsp.Msg = utils.RecodeText(rsp.Code)
		return nil
	}
	logs.Info("user_id:", id)

	/*创建sessionid(唯一随机码)*/
	sessionId := utils.MD5String(req.Mobile + req.Password)
	rsp.SessionId = sessionId

	/*以sessionid为key创建session*/
	bm.Put(sessionId+"name", user.Mobile, time.Second*3600)
	bm.Put(sessionId+"user_id", id, time.Second*3600)
	bm.Put(sessionId+"mobile", user.Mobile, time.Second*3600)

	return nil
}

// Stream is a server side stream handler called via client.Stream or the generated client code
func (e *Register) Stream(ctx context.Context, req *register.StreamingRequest, stream register.Register_StreamStream) error {
	log.Logf("Received Register.Stream request with count: %d", req.Count)

	for i := 0; i < int(req.Count); i++ {
		log.Logf("Responding: %d", i)
		if err := stream.Send(&register.StreamingResponse{
			Count: int64(i),
		}); err != nil {
			return err
		}
	}

	return nil
}

// PingPong is a bidirectional stream handler called via client.Stream or the generated client code
func (e *Register) PingPong(ctx context.Context, stream register.Register_PingPongStream) error {
	for {
		req, err := stream.Recv()
		if err != nil {
			return err
		}
		log.Logf("Got ping %v", req.Stroke)
		if err := stream.Send(&register.Pong{Stroke: req.Stroke}); err != nil {
			return err
		}
	}
}
